/*
 * Dcm_UDS0x3E.c
 *
 *  Created on: 2018-1-16
 *      Author: Shute
 */
#include "UDS.h"


/****************************************************************
                 UDS:TesterPresent (3E hex) service
 ***************************************************************/
#if (STD_ON == DCM_UDS_SERVICE0X3E_ENABLED)
#define DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
FUNC(Std_ReturnType, DCM_CODE)Dcm_UDS0x3E(
		Dcm_OpStatusType OpStatus,
		uint8  ProtocolCtrlId,
		P2VAR(Dcm_NegativeResponseCodeType,AUTOMATIC,DCM_VAR) ErrorCode)
{
	uint8  MsgCtrlId;
	uint8  TxChannelCtrlIndex;
	uint8  TxChannelCfgIndex;
	uint16 Offset;
#if((STD_ON == DCM_SESSION_FUNC_ENABLED) || (STD_ON == DCM_SECURITY_FUNC_ENABLED))
	Std_ReturnType ret;
#endif
    /*************************************************/
#if(STD_ON == DCM_SESSION_FUNC_ENABLED)
    /*session check,check whether the current session supports the request service*/
    ret = DsdInternal_SesCheck(ProtocolCtrlId,SID_TESTER_PRESENT);
    if(E_NOT_OK == ret)
    {
        /****@req DCM-FUNR-073[DCM211]****/
        /*the current session does not support the request service,send NRC = 0x7F*/
        (void)DsdInternal_SetNrc(ProtocolCtrlId,DCM_E_SERVICENOTSUPPORTEDINACTIVESESSION);
        DsdInternal_ProcessingDone(ProtocolCtrlId);
        return E_NOT_OK;
    }
#endif

    /*************************************************/
#if(STD_ON == DCM_SECURITY_FUNC_ENABLED)
    /*security check,check whether the current security supports the request service*/
    ret = DsdInternal_SecurityCheck(ProtocolCtrlId,SID_TESTER_PRESENT);
    if(E_NOT_OK == ret)
    {
        /****@req DCM-FUNR-074[DCM217]****/
        /*the current security does not support the request service,send NRC = 0x33*/
        (void)DsdInternal_SetNrc(ProtocolCtrlId,DCM_E_SECURITYACCESSDENIED);
        DsdInternal_ProcessingDone(ProtocolCtrlId);
        return E_NOT_OK;
    }
#endif

	/*if the required protocol is configuted,get the index of runtime datum*/
	MsgCtrlId = Dcm_ProtocolCtrl[ProtocolCtrlId].MsgCtrlIndex;

	/*check the massage length*/
	if (DCM_UDS0X3E_REQ_DATA_LENGTH != Dcm_MsgCtrl[MsgCtrlId].MsgContext.ReqDataLen)
	{
		/*the length of massage is not correct,send NRC 0x13*/
		(void)DsdInternal_SetNrc(ProtocolCtrlId,DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT);
		DsdInternal_ProcessingDone(ProtocolCtrlId);
		return E_NOT_OK;
	}

	if (DCM_UDS0X3E_ZERO_SUBFUNCTION != Dcm_MsgCtrl[MsgCtrlId].Subfunction)
	{
		/*the required sub-function is not supported,send NRC 0x12*/
		(void)DsdInternal_SetNrc(ProtocolCtrlId,DCM_E_SUBFUNCTIONNOTSUPPORTED);
		DsdInternal_ProcessingDone(ProtocolCtrlId);
		return E_NOT_OK;
	}
    /*************************************************/
#if(STD_ON == DCM_SESSION_FUNC_ENABLED)
    /*session check,check whether the current session supports the request service*/
    ret = DsdInternal_SubSesCheck(ProtocolCtrlId,SID_TESTER_PRESENT);
    if(E_NOT_OK == ret)
    {
        /****@req DCM-FUNR-073[DCM211]****/
        /*the current session does not support the request service,send NRC = 0x7E*/
        (void)DsdInternal_SetNrc(ProtocolCtrlId,DCM_E_SUBFUNCTIONNOTSUPPORTEDINACTIVESESSION);
        DsdInternal_ProcessingDone(ProtocolCtrlId);
        return E_NOT_OK;
    }
#endif

    /*************************************************/
#if(STD_ON == DCM_SECURITY_FUNC_ENABLED)
    /*security check,check whether the current security supports the request service*/
    ret = DsdInternal_SubSecurityCheck(ProtocolCtrlId,SID_TESTER_PRESENT);
    if(E_NOT_OK == ret)
    {
        /****@req DCM-FUNR-074[DCM217]****/
        /*the current security does not support the request service,send NRC = 0x33*/
        (void)DsdInternal_SetNrc(ProtocolCtrlId,DCM_E_SECURITYACCESSDENIED);
        DsdInternal_ProcessingDone(ProtocolCtrlId);
        return E_NOT_OK;
    }
#endif

	/*************************************************/
	/*assemble and send positive response*/
	SchM_Enter_Dcm(Dcm_MsgCtrl);
	TxChannelCtrlIndex = Dcm_MsgCtrl[MsgCtrlId].Dcm_TxCtrlChannelIndex;
	TxChannelCfgIndex = Dcm_ChannelCtrl[TxChannelCtrlIndex].Dcm_ChannelCfgIndex;
	Offset = (Dcm_DslCfg.pDcmChannelCfg)[TxChannelCfgIndex].offset;
    /* check tx data length */
    if((2u) > (Dcm_DslCfg.pDcmChannelCfg[TxChannelCfgIndex].Dcm_DslBufferSize))
    {
        /*Pdu length is bigger than buffer size,ignore the request message */
        (void)DsdInternal_SetNrc(ProtocolCtrlId,DCM_E_RESPONSETOOLONG);
        DsdInternal_ProcessingDone(ProtocolCtrlId);
        return E_NOT_OK;
    }
	Dcm_Channel[Offset] = 0x7E;
	Dcm_Channel[Offset + 1u] =Dcm_MsgCtrl[MsgCtrlId].Subfunction;
	Dcm_MsgCtrl[MsgCtrlId].MsgContext.ResMaxDataLen = 2u;
	Dcm_MsgCtrl[MsgCtrlId].MsgContext.ResDataLen    = 2u;
	Dcm_MsgCtrl[MsgCtrlId].MsgContext.pResData      = &Dcm_Channel[Offset];
	SchM_Exit_Dcm(Dcm_MsgCtrl);
	DsdInternal_ProcessingDone(ProtocolCtrlId);
	return  E_OK;
}
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
#endif
